package com.hiq.gene.engine;

import com.hiq.gene.exception.InvalidTypeException;
import com.hiq.gene.model.Entity;
import com.hiq.gene.model.Types;
import com.hiq.gene.util.StringUtil;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class PostgresqlGenerator {

    private final String dbPath;

    public PostgresqlGenerator(String dbPath) {
        this.dbPath = dbPath;
    }

    public void generate(List<Entity> entities) throws InvalidTypeException {
        File file = new File(dbPath + "tables.sql");
        try {
            PrintWriter pw = new PrintWriter(file);
            for (Entity e : entities) {
                printEntity(pw, e);
                pw.println();
            }
            pw.flush();
            pw.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void printEntity(PrintWriter pw, Entity e) throws InvalidTypeException {
        pw.println("create table " + StringUtil.getDBName(e.getName()) + " (");
        pw.println("   ID SERIAL,");
        pw.println("   primary key(ID),");

        Set<String> keys = e.getFields().keySet();
        Iterator<String> iterator = keys.iterator();
        while (iterator.hasNext()) {
            String fieldName = iterator.next();
            String fieldType = e.getFields().get(fieldName);
            printField(pw, fieldName, fieldType);
            if (iterator.hasNext()) {
                pw.println(",");
            } else {
                pw.println();
            }
        }
        pw.println(");");
    }

    private void printField(PrintWriter pw, String fieldName, String fieldType) throws InvalidTypeException {
        String dbName = getDbName(fieldType, fieldName);
        String dbType = Types.getPGType(fieldType);
        pw.print("   " + dbName + " " + dbType);
    }

    private String getDbName(String fieldType, String fieldName) {
        if (fieldType.startsWith("@")) {
            return StringUtil.getDBName(fieldName) + "_ID";
        } else {
            return StringUtil.getDBName(fieldName);
        }
    }
}
